package com.zhiletu.collect;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import javax.script.ScriptException;

import com.zhiletu.collect.config.CollectConfig;
import com.zhiletu.collect.config.RuleConfig;
import com.zhiletu.collect.entry.WordDictEntry;
import com.zhiletu.collect.util.DBUtil;
import com.zhiletu.collect.util.RegExMatcher;
import com.zhiletu.collect.util.ScriptingAPI;

/**
 *
 * @Title: 百度词典客户端查询
 * @Package com.zhiletu.collect
 * @Description: TODO
 * @author zhiletu.com
 * @date 2021年3月11日
 * @version V1.0
 */
public class DictTool {
	/**
	 * @Title: queryDict
	 * @Description: 查询百度词典，并保存词典，并返回词组简介
	 * @param keyword
	 * @return
	 * @throws Exception
	 */
	public static String queryDict(String keyword) throws Exception {
		List<Map<String, Object>> list = RuleConfig.querySql("select mean_simple,mean_detail,mean_baike from `collect`.`word_dict` where word_text=?", new Object[] { keyword.trim() });
		String mean = null;
		if (list.isEmpty()) {
			StringBuffer html = Collecter.readStream("https://dict.baidu.com/s?wd=" + URLEncoder.encode(keyword, "UTF-8"), true, "utf-8");
			/*去掉所有的html标记(除了p标签)*/
			String delHtmlTag = "function delHtmlTag(str){str = str.replace(/<script[^>]*?>[\\s\\S]*?<\\/script>/g,\"\"); str = str.replace(/<style[^>]*?>[\\s\\S]*?<\\/style>/g,\"\"); return str.replace(/<(?!\\/?[pP])[^>]+>/g,\"\");}";

			String content = ScriptingAPI.invokeScript(delHtmlTag, "delHtmlTag", new Object[] { html.toString() });
			html = null;
			Map word = findBaiduDict(keyword, content);
			content = null;
			if (word == null || word.isEmpty())
				return null;
			saveDict(word);

			Object temp = null;
			mean = word.isEmpty() ? null :
					(temp = word.get(WordDictEntry.mean_simple)) == null ?
							((temp = word.get(WordDictEntry.mean_detail)) == null ?
									((temp = word.get(WordDictEntry.mean_baike)) == null ? null : temp.toString())
									: temp.toString())
							: temp.toString();
			word = null;
			temp = null;
		}
		else {
			Map m = list.get(0);
			Object temp = m.get(WordDictEntry.mean_simple);
			if (temp == null) {
				temp = m.get(WordDictEntry.mean_detail);
				if (temp == null) {
					temp = m.get(WordDictEntry.mean_baike);
				}
			}
			list = null;
			m = null;
			mean = temp == null ? null : temp.toString();
		}

		return removePforMobile(mean);
	}

	/**
	 * 手机端不支持p标签，pc支持
	 * @param mean
	 * @return
	 * @throws ScriptException
	 * @throws NoSuchMethodException
	 */
	private static String removePforMobile(String mean) throws ScriptException, NoSuchMethodException {
		if (mean == null)
			return null;
		String remove = "function delHtmlTag(str){str = str.replace(/<\\/p>/g,\"\\n\"); return str.replace(/<[^>]+>/g,\"\");}";
		String content = ScriptingAPI.invokeScript(remove, "delHtmlTag", new Object[] { mean });
		remove = null;
		return content;
	}

	/**
	 * 保存单词到词典库
	 * @param word
	 */
	@SuppressWarnings("rawtypes")
	public static void saveDict(Map word) {
		Object ws = word.get(WordDictEntry.word_same);
		Object wr = word.get(WordDictEntry.word_reverse);
		Object wi = word.get(WordDictEntry.word_info);
		Object wd = word.get(WordDictEntry.word_relation);
		RuleConfig.update("insert into `collect`.`word_dict`(word_text, lang_type, word_read, word_nature, mean_simple, mean_detail, word_simple, word_same, word_reverse, mean_online, mean_baike, word_relation, word_info) values(?,?,?,?,?,?,?,?,?,?,?,?,?)",
				new Object[] { word.get(WordDictEntry.word_text),
						word.get(WordDictEntry.lang_type),
						word.get(WordDictEntry.word_read),
						word.get(WordDictEntry.word_nature),
						word.get(WordDictEntry.mean_simple),
						word.get(WordDictEntry.mean_detail),
						word.get(WordDictEntry.word_simple),
						RegExMatcher.regexReplace(ws == null ? "" : ws.toString(), "[' ']+", ","),
						RegExMatcher.regexReplace(wr == null ? "" : wr.toString(), "[' ']+", ","),
						word.get(WordDictEntry.mean_online),
						word.get(WordDictEntry.mean_baike),
						RegExMatcher.regexReplace(wd == null ? "" : wd.toString(), "[' ']+", ","),
						RegExMatcher.regexReplace(wi == null ? "" : wi.toString(), "[' ']+", ",")
				});
		ws = wr = wi = wd = null;
	}

	/**
	 * 根据百度词典获取关键词意义
	 * @param wordText
	 * @param content
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Map findBaiduDict(String wordText, String content) {
		// 找不到
		if (content.indexOf("抱歉，百度词典中没有收入") > -1 || content.indexOf("抱歉：百度汉语中没有收录相关结果") > -1 || "0".equals(wordText))
			return null;

		Map word = new HashMap();
		word.put(WordDictEntry.word_text, wordText);
		try {
			// 英文
			if (content.indexOf("[英]") > -1 || wordText.matches("[a-z|A-Z]")) {
				word.put(WordDictEntry.lang_type, WordDictEntry.value_lang_type_en);
				int end = 0;
				// 英文单词
				if ((end = content.indexOf("柯林斯高")) > -1) {
					content = content.substring(0, end);
				}

				if ((end = content.indexOf("简明释义")) > -1) {
					String temp = content.substring(end + 4).replaceAll(" ", "");

					int st = 0;
					if ((st = temp.indexOf("例句")) > -1)
						temp = temp.substring(0, st);
					word.put(WordDictEntry.mean_simple, temp);
					content = content.substring(0, end);
				}

				if ((end = content.indexOf("百度首页")) > -1) {
					String temp = content.substring(end + 4).replaceAll(" ", "").replace("&nbsp;", "");
					int st = 0;
					if ((st = temp.indexOf("生词本")) > -1)
						temp = temp.substring(0, st);
					String error = "抱歉：百度汉语中没有收录相关结果";
					String wr;
					word.put(WordDictEntry.word_read,
							(st = temp.indexOf("[")) > -1 ?
									((wr = temp.substring(st)).startsWith(error) ?
											wr : "")
									: temp);
					//content = content.substring(0, end);
				}
			}
			else {
				word.put(WordDictEntry.lang_type, WordDictEntry.value_lang_type_zh);
				// 中文词组
				int end = 0;
				if (wordText.length() > 1) {
					if ((end = content.indexOf("相关字词")) > -1) {
						content = content.substring(0, end);
					}

					if ((end = content.indexOf("百度释义")) > -1) {
						String temp = content.substring(end + 4).replaceAll(" ", "").replace("查看百科", "");
						int st = 0;
						if ((st = temp.indexOf("</p>")) > -1)
							temp = temp.substring(0, st + 4);
						word.put(WordDictEntry.mean_baike, temp);
						content = content.substring(0, end);
					}

					if ((end = content.indexOf("网络解释")) > -1) {
						String temp = content.substring(end + 4).replaceAll(" ", "");
						word.put(WordDictEntry.mean_online, temp);
						content = content.substring(0, end);
					}

					if ((end = content.indexOf("反义词")) > -1 && content.indexOf("近反义词") < end - 1) {
						String temp = content.substring(end + 3).trim();//去收尾空格，后期再处理间隔
						word.put(WordDictEntry.word_reverse, temp);
						content = content.substring(0, end);
					}

					if ((end = content.indexOf("近义词")) > -1) {
						String temp = content.substring(end + 3).trim();//去收尾空格，后期再处理间隔
						word.put(WordDictEntry.word_same, temp);
						content = content.substring(0, end);
					}

					if ((end = content.lastIndexOf("详细解释")) > -1 && content.substring(end).indexOf("基本释义") == -1) {
						String temp = content.substring(end + 4).replaceAll(" ", "");
						int st = 0;
						if ((st = temp.indexOf("︾查看更多")) > -1)
							temp = temp.substring(0, st);
						word.put(WordDictEntry.mean_detail, temp.length() > 4000 ? temp.substring(0, 3900) : temp);
						content = content.substring(0, end);
					}

					if ((end = content.indexOf("基本释义")) > -1) {
						String temp = content.substring(end + 4).replaceAll(" ", "");
						int st = 0;
						if ((st = temp.indexOf("︾查看更多")) > -1)
							temp = temp.substring(0, st).replace("详细解释", "");
						word.put(WordDictEntry.mean_simple, temp);
						content = content.substring(0, end);
					}

					if ((end = content.indexOf("百度首页")) > -1) {
						String temp = content.substring(end + 4).replaceAll(" ", "").replace("&nbsp;", "");
						int st = 0;
						if ((st = temp.indexOf("生词本")) > -1)
							temp = temp.substring(0, st);
						String error = "抱歉：百度汉语中没有收录相关结果";
						String wr;
						word.put(WordDictEntry.word_read,
								(st = temp.indexOf("[")) > -1 ?
										((wr = temp.substring(st)).startsWith(error) ?
												wr : "")
										: temp);
						//content = content.substring(0, end);
					}
				}
				else {
					// 中文单字
					if ((end = content.indexOf("相关字")) > -1) {
						content = content.substring(0, end);
					}

					if ((end = content.indexOf("百度释义")) > -1) {
						String temp = content.substring(end + 4).replaceAll(" ", "").replace("查看百科", "");
						int st = 0;
						if ((st = temp.indexOf("</p>")) > -1)
							temp = temp.substring(0, st + 4);
						word.put(WordDictEntry.mean_baike, temp);
						content = content.substring(0, end);
					}

					if ((end = content.indexOf("相关组词")) > -1) {
						String temp = content.substring(end + 4).trim();
						word.put(WordDictEntry.word_relation, temp);
						content = content.substring(0, end);
					}


					if ((end = content.indexOf("其他信息")) > -1) {
						String temp = content.substring(end + 4).trim();
						word.put(WordDictEntry.word_info, temp);
						content = content.substring(0, end);
					}

					if ((end = content.indexOf("详细解释")) > -1 && content.substring(end).indexOf("基本释义") == -1) {
						String temp = content.substring(end + 4).replaceAll(" ", "");
						int st = 0;
						if ((st = temp.indexOf("︾查看更多")) > -1)
							temp = temp.substring(0, st);
						word.put(WordDictEntry.mean_detail, temp.length() > 4000 ? temp.substring(0, 3900) : temp);
						content = content.substring(0, end);
					}

					if ((end = content.indexOf("基本释义")) > -1) {
						String temp = content.substring(end + 4).replaceAll(" ", "");
						int st = 0;
						if ((st = temp.indexOf("︾查看更多")) > -1)
							temp = temp.substring(0, st).replace("详细解释", "");
						word.put(WordDictEntry.mean_simple, temp);
						content = content.substring(0, end);
					}

					if ((end = content.indexOf("百度首页")) > -1) {
						String temp = content.substring(end + 4).replaceAll(" ", "");
						int st = 0;
						if ((st = temp.indexOf("生词本")) > -1)
							temp = temp.substring(0, st);
						word.put(WordDictEntry.word_read, (st = temp.indexOf("拼 音")) > -1 ? temp.substring(st, temp.indexOf("&nbsp;")) : temp);
						Object wd = word.get(WordDictEntry.word_info);
						word.put(WordDictEntry.word_info, temp + (wd == null ? "" : wd.toString()));
						//content = content.substring(0, end);
					}
				}
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		return word;
	}

	public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException, InterruptedException {
		File sourcefile = new File("d:\\所有常用汉字大全(7000).txt");
		String sourcecharset = "gbk";
		Scanner scan = new Scanner(sourcefile, sourcecharset);
		StringBuilder sb = new StringBuilder();
		while (scan.hasNext()) {
			String all = scan.nextLine();
			sb.append(all);
		}

		//System.out.println(URLDecoder.decode(URLEncoder.encode(sb.toString(), "UTF-8"), "UTF-8"));

//    	char[] ks = sb.toString().toCharArray();//.split(",");
//    	for (int x = 0; x < ks.length; x++){
//    		//System.out.println(String.valueOf(ks[x]) + x);
//    		try {
//				localDict(String.valueOf(ks[x]));
//			} catch (UnsupportedEncodingException e) { 
//				e.printStackTrace();
//			} catch (ScriptException e) { 
//				e.printStackTrace();
//			} catch (NoSuchMethodException e) { 
//				e.printStackTrace();
//			} catch (Exception e){ 
//				System.out.println(ks[x]);
//				e.printStackTrace();
//			}
//    		if (x%100==0){
//    			System.out.println("ok: "+x);
//    			Thread.sleep(50);
//    		} 
//    	}
	}

	/**
	 * 本地批量灌数据
	 * @param keyword
	 * @throws ScriptException
	 * @throws NoSuchMethodException
	 * @throws UnsupportedEncodingException
	 */
	public static void localDict(String keyword) throws Exception {
		StringBuffer html = Collecter.readStream("http://dict.baidu.com/s?wd=" + URLEncoder.encode(keyword, "UTF-8"), true, "utf-8");
		/*去掉所有的html标记(除了p标签)*/
		String delHtmlTag = "function delHtmlTag(str){str = str.replace(/<script[^>]*?>[\\s\\S]*?<\\/script>/g,\"\"); str = str.replace(/<style[^>]*?>[\\s\\S]*?<\\/style>/g,\"\"); return str.replace(/<(?!\\/?[pP])[^>]+>/g,\"\");}";

		String content = ScriptingAPI.invokeScript(delHtmlTag, "delHtmlTag", new Object[] { html.toString() });
		Map word = findBaiduDict(keyword, content);
		if (word == null || word.isEmpty())
			return;
		saveDictLocal(word);
		word = null;
	}

	/**
	 * 保存单词到生产环境词典库
	 * @param word
	 */
	@SuppressWarnings("rawtypes")
	public static void saveDictLocal(Map word) throws Exception {
		Object ws = word.get(WordDictEntry.word_same);
		Object wr = word.get(WordDictEntry.word_reverse);
		Object wi = word.get(WordDictEntry.word_info);
		Object wd = word.get(WordDictEntry.word_relation);
		String sql = "insert into `collect`.`word_dict`(word_text, lang_type, word_read, word_nature, mean_simple, mean_detail, word_simple, word_same, word_reverse, mean_online, mean_baike, word_relation, word_info) values(?,?,?,?,?,?,?,?,?,?,?,?,?)";
		Object[] parArray = new Object[] { word.get(WordDictEntry.word_text),
				word.get(WordDictEntry.lang_type),
				word.get(WordDictEntry.word_read),
				word.get(WordDictEntry.word_nature),
				word.get(WordDictEntry.mean_simple),
				word.get(WordDictEntry.mean_detail),
				word.get(WordDictEntry.word_simple),
				RegExMatcher.regexReplace(ws == null ? "" : ws.toString(), "[' ']+", ","),
				RegExMatcher.regexReplace(wr == null ? "" : wr.toString(), "[' ']+", ","),
				word.get(WordDictEntry.mean_online),
				word.get(WordDictEntry.mean_baike),
				RegExMatcher.regexReplace(wd == null ? "" : wd.toString(), "[' ']+", ","),
				RegExMatcher.regexReplace(wi == null ? "" : wi.toString(), "[' ']+", ",")
		};

		String url = CollectConfig.getDBname();
		String username = CollectConfig.getUsername();
		String passwd = CollectConfig.getPasswd();
		DBUtil.update(sql, parArray, url, username, passwd);
	}
}
